package com.junci.mtest.model.repository;


import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.google.gson.Gson;
import com.junci.mtest.MyApplication;
import com.junci.mtest.model.bean.DefaultBean;
import com.junci.mtest.model.bean.ErrorMessage;
import com.junci.mtest.model.bean.MySelfInfo;
import com.junci.mtest.model.http.HttpCache;
import com.junci.mtest.model.http.HttpClient;
import com.junci.mtest.model.http.MyInterfaceRetrofit;
import com.junci.mtest.model.http.OtherInterfaceRetrofit;
import com.junci.mtest.model.service.HttpGetDefaultService;
import com.junci.mtest.model.service.HttpPostDefaultService;
import com.junci.mtest.model.service.HttpPostExecuteDefaultService;
import com.junci.mtest.utils.LogUtil;
import com.junci.mtest.views.BaseActivity;


import org.json.JSONObject;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;



/**
 * 尼莫
 * 关于网络的默认底层API
 */

public class HttpDefaultRepository<T extends DefaultBean> {

    private Disposable disposable;  // 请求对象，可以取消请求
    private Call<ResponseBody> mExecutePost;

    @Deprecated
    public interface Callback {
        void success(Object bean);

        void failed(ErrorMessage errorMessage);
    }

    @Deprecated
    public interface Callback2 {
        void success(Object bean);

        void cache(Object bean);

        void failed(ErrorMessage errorMessage);
    }
    //    CompositeSubscription mCompositeSubscription;

    /**
     * 取消请求 绑定了activity 来自动取消
     */
    public void cancelRequest() {
        if (disposable != null) {
            disposable.dispose();
        }
        if (mExecutePost != null) {
            mExecutePost.cancel();
        }
    }

    /**
     * 是否取消了请求
     *
     * @return
     */
    @Deprecated
    public boolean isCancelRequest() {
        if (disposable != null) {
            return disposable.isDisposed();
        }
        return false;
    }

    public Disposable post(@NonNull final String url, Map<String, String> map, final Class clazz, final boolean isCache, final HttpDefaultCallback<T> callback) {
        if (!TextUtils.isEmpty(url)) {

            return post(url, map, clazz, isCache, callback, true);
        }else{
            return null;
        }
    }

    /**
     * 普通的get请求
     *
     * @param url      完整的url
     * @param map      携带的参数 key-value的格式
     * @param clazz    返回对象的JavaBean
     * @param callback 回调
     */
    public void get(@NonNull final String url, Map<String, String> map, final Class clazz, final boolean isCache, final HttpDefaultCallback<T> callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        try {
            if (isCache) {
                try {
                    // 需要先从缓存拿数据
                    String str = HttpCache.getInstance().getCache(url, map);
                    Gson gson = new Gson();
                    T bean = (T) gson.fromJson(str, clazz);
                    if (bean != null && callback != null) {
                        LogUtil.s("成功从缓存获取到数据 form：" + url + "\n" + bean);
                        callback.cache(bean);
                    }
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
            if (map == null) {
                map = new HashMap<>();
            }
            final Map<String, String> finalMap = map;
            if (HttpClient.keys.length>0) {
                List<String> list = HttpClient.getValues();
                for (int i = 0; i < HttpClient.keys.length; i++) {
                    finalMap.put(HttpClient.keys[i],list.get(i));
                }
            }
            OtherInterfaceRetrofit.getRetrofit()
                    .create(HttpGetDefaultService.class)
                    .request(url, map)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<ResponseBody>() {

                        @Override
                        public void onError(Throwable e) {
                            if (callback != null) {
                                callback.failed(ErrorMessage.createByReqError(e));
                            }
                        }

                        @Override
                        public void onComplete() {

                        }

                        @Override
                        public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

                        }

                        @Override
                        public void onNext(ResponseBody body) {
                            try {
                                String string = body.string();
                                JSONObject json = new JSONObject(string);
                                if (isCache) {
                                    // 需要缓存
                                    HttpCache.getInstance().saveData(url, finalMap, json.toString());
                                }
                                Gson gson = new Gson();
                                T bean = (T) gson.fromJson(json.toString(), clazz);
                                if (bean != null && bean.getCode() ==1 && callback != null) {
                                    // 正确获取到数据
                                    callback.success(bean);
                                } else if (callback != null) {
                                    // 数据是空的
                                    callback.failed(ErrorMessage.create(bean == null ? "没有获取到数据！可能是服务端返回为空，可能是数据解析错误！" : bean.getMsg()));
                                }
                            } catch (Exception e) {
                                callback.failed(ErrorMessage.createByReqError(e));
                                e.printStackTrace();
                            }
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
            callback.failed(ErrorMessage.createByNotNetwork(e));
        }

    }



    /**
     * 普通的POST请求（异步）
     * @param url                  完整的url
     * @param map                  携带的参数 key-value的格式
     * @param clazz                返回对象的JavaBean类型
     * @param isCache              是否缓存 如果为true 则会先去缓存里取数据 目前不需要缓存 留作处理
     * @param callback             回调
     * @param isBindToActivityLife 是否和当前activity 生命周期相关 默认为true 相关（相关时，Activity销毁时，接口会跟着停止请求）
     */
    public Disposable post(@NonNull final String url, Map<String, String> map, final Class clazz, final boolean isCache, final HttpDefaultCallback callback, boolean isBindToActivityLife) {
        try {
            if (isCache) {
                try {
                    // 需要先从缓存拿数据
                    String str = HttpCache.getInstance().getCache(url, map);

                    Gson gson = new Gson();
                    T bean = (T) gson.fromJson(str, clazz);
                    if (bean != null && callback != null) {
                        if (LogUtil.isLog()) {
                            LogUtil.s("成功从缓存获取到数据 form：" + url + "\n" + bean);
                        }
                        callback.cache(bean);
                    } else if (bean == null && callback != null) {
                        callback.noCache();
                    }
                } catch (Exception x) {
                    if (callback != null) {
                        callback.noCache();
                    }
                    x.printStackTrace();
                }
            }


            if (map == null) {
                map = new HashMap<>();
            }
            final Map<String, String> finalMap = map;
            try {
                // 如果存在多个对象，先取消上一次请求
                if (disposable != null) {
                    disposable.dispose();
                }
            } catch (Exception e) {
            }


            MyInterfaceRetrofit.getRetrofit()
                    .create(HttpPostDefaultService.class)
                    .request(url, map)

                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<ResponseBody>() {

                        @Override
                        public void onError(Throwable e) {
                            if (LogUtil.isLog()){
                                LogUtil.s("~~~~~~~onError~~~~~"+url);
                            }
                            e.printStackTrace();
                            if (callback != null) {
                                callback.failed(ErrorMessage.create(""));
                            }
                        }

                        @Override
                        public void onComplete() {

                        }

                        @Override
                        public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
                            try {
                                if (isBindToActivityLife) {//和当前activity生命周期相关连
                                    BaseActivity baseActivity = (BaseActivity) MyApplication.application.currentActivity.get();
                                    baseActivity.addSubscrebe(d);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onNext(ResponseBody body) {
                            try {
                                String string = body.string();
                                JSONObject json = new JSONObject(string);
                                int code = json.optInt("code");
                                if (code==0) {

                                    try {
                                        Gson gson = new Gson();
                                         T bean;

                                         bean = (T) gson.fromJson(string, clazz);

//
//                                        LogUtil.s("------------"+obj);


                                        if(bean!=null&&callback!=null){
                                            callback.success(bean);
                                            if (isCache) {
                                                // 需要缓存
                                                HttpCache.getInstance().saveData(url, finalMap, json.toString());
                                            }
                                        }else if(callback!=null){
                                            callback.failed(ErrorMessage.create(bean.getMsg(),0));
                                        }
                                    }catch (Exception e){
                                        if (LogUtil.isLog()) {
                                            e.printStackTrace();
                                        }
                                        callback.failed(ErrorMessage.create(e.getMessage()));
                                    }
                                }else {
                                    callback.failed(ErrorMessage.create(json.getString("msg"),0));
                                }
                            } catch (Exception e) {
                                if (callback != null) {
                                    callback.failed(ErrorMessage.create(""));
                                }
                                e.printStackTrace();
                            }
                        }
                    });


            return disposable;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 普通的POST请求（同步） 因为是耗时操作 所以需要在子线程操作
     * @param url   完整的url
     * @param map   携带的参数 key-value的格式
     * @param clazz 返回对象的JavaBean类型
     * @return 返回传入的JavaBean类型(如果请求失败, 为null)
     */
    public T postExecute(@NonNull final String url, Map<String, String> map, final Class clazz) {
        try {
            // 怎么搞成子线程 还是同步返回的。。。
            if (map == null) {
                map = new HashMap<>();
            }
            mExecutePost = MyInterfaceRetrofit.getRetrofit()
                    .create(HttpPostExecuteDefaultService.class)
                    .request(url, map);
            Response<ResponseBody> execute = mExecutePost.execute();
            String string = execute.body().string();
            Gson gson = new Gson();
            final T bean = (T) gson.fromJson(string, clazz);
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
